package cn.wind.xboot.module.app.v1.handler;

import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;
import cn.wind.xboot.core.utils.JsonUtil;
import cn.wind.xboot.core.utils.SpringUtil;
import cn.wind.xboot.core.utils.ThreadPoolUtil;
import cn.wind.xboot.core.utils.UserUtil;
import cn.wind.xboot.logic.cli.entity.CliLog;
import cn.wind.xboot.logic.cli.service.ICliLogService;
import cn.wind.xboot.logic.cli.service.impl.CliLogServiceImpl;
import cn.wind.klog.annotation.Log;
import cn.wind.klog.annotation.LogFilterType;
import cn.wind.klog.handlers.LogHandler;
import cn.wind.klog.handlers.LogHandlerHelp;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * <p>Title: MyLogAroundHandler</p>
 * <p>Description: TODO</p>
 *
 * @author xukk
 * @version 1.0
 * @date 2018/6/29
 */
public class AppMyLogHandler implements LogHandler<Log, Object> {

    private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<Date>("ThreadLocal beginTime");

    @Override
    public Object handlerBefore(Log log, JoinPoint joinPoint) {
        //线程绑定变量（该数据只有当前请求的线程可见）
        Date beginTime = new Date();
        beginTimeThreadLocal.set(beginTime);
        return null;
    }

    @Override
    public Object handlerAfter(Log log, JoinPoint joinPoint, Object o) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String currentUser= UserUtil.principal();
        long beginTime = beginTimeThreadLocal.get().getTime();
        Object[] args = joinPoint.getArgs();
        JSONObject jsonObject = new JSONObject();
        if (args != null && args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof JSONObject) {
                    jsonObject = (JSONObject) args[i];
                    break;
                }
            }
        }
        String value = log.filterType().equals(LogFilterType.String) ? log.value() : LogHandlerHelp.executeTemplate(log.pattern(), joinPoint);
        String extra="";
        if(StringUtils.isNotBlank(log.extra())){
            extra=LogHandlerHelp.executeTemplate(log.extra(),joinPoint);
        }
        CliLog cliLog = new CliLog();
        //日志标题
        cliLog.setName(value);
        //日志请求url
        cliLog.setRequestUrl(request.getRequestURI());
        //请求方式
        cliLog.setRequestType(request.getMethod());
        //请求用户
        cliLog.setUsername(currentUser);
        //请求IP
        cliLog.setIp(HttpUtil.getClientIP(request));
        cliLog.setDeleteFlag(0);
        //IP地址
        cliLog.setUsername(currentUser!=null? ReUtil.getGroup0("(?<=\\.*)\\d+",currentUser):"");
        cliLog.setRequestParam(JsonUtil.toJson(joinPoint.getArgs()));
        cliLog.setCreateBy(currentUser);
        cliLog.setUpdateBy(cliLog.getCreateBy());
        cliLog.setCreateTime(new Date());
        cliLog.setUpdateTime(cliLog.getCreateTime());
        cliLog.setModule(log.module());
        cliLog.setAction(log.action());
        cliLog.setChannel(log.channel());
        cliLog.setExtra(extra);
        cliLog.setResult(o==null?"failure":"success");
        cliLog.setChannelDetail(jsonObject.getString("device"));
        if(jsonObject.getString("userId")!=null){
            cliLog.setUsername(jsonObject.getString("userId"));
        }
        long endTime = System.currentTimeMillis();
        //请求耗时
        Long logElapsedTime = endTime - beginTime;
        cliLog.setCostTime(logElapsedTime.intValue());
        ThreadPoolUtil.getPool().execute(() ->{
            ICliLogService sysLogService = SpringUtil.getBean(CliLogServiceImpl.class);
            sysLogService.save(cliLog);
         });
        return null;
    }
}
